package com.datang.litejvm.clz;


import com.datang.litejvm.constant.ConstantClassInfo;
import com.datang.litejvm.constant.ConstantPool;
import com.datang.litejvm.constant.ConstantUTF8Info;

import java.util.Iterator;
import java.util.List;

/**
 * @author: 顶风少年
 * @Description: Class类
 * @date: 13:55 2022/6/10
 **/
public class Class {


    //魔数
    private String magic;

    //小版本号
    private int minorVersion;

    //大版本号
    private int majorVersion;

    //常量池
    private com.datang.litejvm.constant.ConstantPool pool;

    //访问标记
    private ClassAccessFlag classAccessFlag;

    //类
    private int thisClassIndex;


    //父类
    private int superClassIndex;

    private String superClassName;

    //接口引用
    private List<Integer> interfaceIndexList;

    //属性列表
    private List<Field> fieldList;

    //方法
    private List<Method> methodList;

    //-------------------------------------------------------

    /**
     * @author: 顶风少年
     * @Description: 魔数
     * @date: 11:39 2022/6/10
     **/
    public String getMagic() {
        return magic;
    }

    /**
     * @author: 顶风少年
     * @Description: 魔数
     * @date: 11:39 2022/6/10
     **/
    public void setMagic(String magic) {
        this.magic = magic;
    }

    /**
     * @author: 顶风少年
     * @Description: 小版本号
     * @date: 11:28 2022/6/10
     **/
    public int getMinorVersion() {
        return minorVersion;
    }

    /**
     * @author: 顶风少年
     * @Description: 小版本号
     * @date: 11:28 2022/6/10
     **/
    public void setMinorVersion(int minorVersion) {
        this.minorVersion = minorVersion;
    }

    /**
     * @author: 顶风少年
     * @Description: 大版本号
     * @date: 11:28 2022/6/10
     **/
    public int getMajorVersion() {
        return majorVersion;
    }

    /**
     * @author: 顶风少年
     * @Description: 大版本号
     * @date: 11:28 2022/6/10
     **/
    public void setMajorVersion(int majorVersion) {
        this.majorVersion = majorVersion;
    }

    /**
     * @author: 顶风少年
     * @Description: 常量池
     * @date: 11:28 2022/6/10
     **/
    public ConstantPool getConstantPool() {
        return pool;
    }

    /**
     * @author: 顶风少年
     * @Description: 常量池
     * @date: 11:28 2022/6/10
     **/
    public void setConstPool(ConstantPool pool) {
        this.pool = pool;
    }

    /**
     * @author: 顶风少年
     * @Description: 访问标记
     * @date: 17:18 2022/6/10
     **/
    public ClassAccessFlag getAccessFlag() {
        return classAccessFlag;
    }

    /**
     * @author: 顶风少年
     * @Description: 访问标记
     * @date: 17:18 2022/6/10
     **/
    public void setAccessFlag(ClassAccessFlag classAccessFlag) {
        this.classAccessFlag = classAccessFlag;
    }

    /**
     * @author: 顶风少年
     * @Description: 类
     * @date: 17:18 2022/6/10
     **/
    public int getThisClassIndex() {
        return thisClassIndex;
    }

    public void setThisClassIndex(int thisClassIndex) {
        this.thisClassIndex = thisClassIndex;
    }

    /**
     * @author: 顶风少年
     * @Description: 父类
     * @date: 17:18 2022/6/10
     **/
    public int getSuperClassIndex() {
        return superClassIndex;
    }

    public void setSuperClassIndex(int superClassIndex) {
        this.superClassIndex = superClassIndex;
        ConstantClassInfo constantClassInfo = (ConstantClassInfo) pool.getConstantInfo(superClassIndex);
        this.superClassName = constantClassInfo.getClassName();
    }

    public String getSuperClassName() {
        return superClassName;
    }

    /**
     * @author: 顶风少年
     * @Description: 接口
     * @date: 17:18 2022/6/10
     **/
    public List<Integer> getInterfaceIndexList() {
        return interfaceIndexList;
    }

    public void setInterfaceIndexList(List<Integer> interfaceIndexList) {
        this.interfaceIndexList = interfaceIndexList;
    }

    /**
     * @author: 顶风少年
     * @Description: 属性列表
     * @date: 11:22 2022/6/12
     **/
    public List<Field> getFieldList() {
        return fieldList;
    }

    /**
     * @author: 顶风少年
     * @Description: 属性列表
     * @date: 11:22 2022/6/12
     **/
    public void setFieldList(List<Field> fieldList) {
        this.fieldList = fieldList;
    }

    /**
     * @author: 顶风少年
     * @Description: 方法
     * @date: 18:31 2022/6/12
     **/
    public List<Method> getMethodList() {
        return methodList;
    }

    /**
     * @author: 顶风少年
     * @Description: 方法
     * @date: 18:31 2022/6/12
     **/
    public void setMethodList(List<Method> methodList) {
        this.methodList = methodList;
    }


    /**
     * @author: 顶风少年
     * @Description: 根据方法名和方法签名查询方法
     * @date: 10:47 2022/6/16
     **/
    public Method getMethod(String methodName, String paramAndResultType) {
        Method rMethod = null;
        Iterator<Method> iter = methodList.iterator();
        while (iter.hasNext()) {
            Method method = iter.next();
            int nameIndex = method.getNameIndex();
            int descriptorIndex = method.getDescriptorIndex();

            ConstantUTF8Info nameInfo = (ConstantUTF8Info) pool.getConstantInfo(nameIndex);
            ConstantUTF8Info descriptorInfo = (ConstantUTF8Info) pool.getConstantInfo(descriptorIndex);

            if (nameInfo.getBytes().equals(methodName) && descriptorInfo.getBytes().equals(paramAndResultType)) {
                rMethod = method;
            }
        }
        return rMethod;
    }

    /**
     * @author: 顶风少年
     * @Description: 查询main方法
     * @date: 10:36 2022/6/16
     **/
    public Method getMainMethod() {
        return getMethod("main", "([Ljava/lang/String;)V");
    }
}
